package br.com.ozsolucoes.managedbean.negocio.servico;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

import org.joda.time.DateTime;
import org.joda.time.Days;

import br.com.ozsolucoes.entity.Categoria;
import br.com.ozsolucoes.entity.Cliente;
import br.com.ozsolucoes.entity.Contas;
import br.com.ozsolucoes.entity.Servico;
import br.com.ozsolucoes.entity.ServicoCategoria;
import br.com.ozsolucoes.entity.ServicoCategoriaPK;
import br.com.ozsolucoes.managedbean.base.BaseManagedBean;
import br.com.ozsolucoes.sessionbeans.CategoriaSessionBean;
import br.com.ozsolucoes.sessionbeans.ContasSessionBean;
import br.com.ozsolucoes.sessionbeans.ServicoSessionBean;
import br.com.ozsolucoes.util.ClienteSessaoManagedBean;
import br.com.ozsolucoes.util.Constantes;

@ManagedBean
@ViewScoped
public class AlterarServicoManagedBean extends BaseManagedBean {

	public AlterarServicoManagedBean() {
		super();
	}

	@PostConstruct
	public void init() {
		categoriasCliente = categoriaSessionBean.consultarCategoriasVingente(getServicoVingente().getId());
	}

	@EJB
	private ServicoSessionBean servicoSessionBean;
	@EJB
	private CategoriaSessionBean categoriaSessionBean;
	@EJB
	private ContasSessionBean contasSessionBean;

	private Servico servicoVingente = new Servico();
	private List<Categoria> categoriasCliente = new ArrayList<Categoria>();
	private List<Categoria> categoriasAdicionar = new ArrayList<Categoria>();
	private List<Categoria> categoriasAdicionarCliente = new ArrayList<Categoria>();
	private List<Categoria> categoriasRemover = new ArrayList<Categoria>();
	private List<Categoria> categoriasRemoverCliente = new ArrayList<Categoria>();

	private double valorAtualizado;

	private int tipoOp;

	public String alterarServico() {
		servicoVingente.setValorMensal(valorAtualizado);
		switch (tipoOp) {
		case 1:
			categoriasCliente.addAll(categoriasAdicionarCliente);
			populaServicoCategoria(categoriasCliente);
			try {
				atualizarContas();
				servicoSessionBean.alterarServico(servicoVingente);
				addMessageInfo("Categorias Adicionadas com sucesso!");
				return meuPerfil();
			} catch (Exception e) {
				addMessageError("Erro ao adicionar categorias! \n" + e.toString());
				return null;
			}
		case 2:
			populaServicoCategoriaRemove(categoriasRemoverCliente);
			atualizarContas();
			try {
				servicoSessionBean.alterarServico(servicoVingente);
				for (ServicoCategoria sc : servicoVingente.getServicoCategoria()) {
					servicoSessionBean.removerServicoCategoria(sc);
				}
				addMessageInfo("Categorias Removidas com sucesso!");
				return meuPerfil();
			} catch (Exception e) {
				addMessageError("Erro ao remover categorias! \n" + e.toString());
				return null;
			}
		}
		return null;
	}

	@SuppressWarnings("deprecation")
	public void atualizarContas() {
		double precoAcerto = 0;
		DateTime dataAtual = new DateTime();
		Cliente cliente = ClienteSessaoManagedBean.getInstance().getClienteSessao();
		List<Contas> contasPendentes = contasSessionBean.consultarContasPendentesClientePorServico(cliente.getId(), servicoVingente.getId());
		Contas proxConta = contasPendentes.get(0);
		if (null == contasSessionBean.consultarUltimaContaCliente(cliente.getId())) {
			Date dtInicio = servicoVingente.getDataInicio();
			DateTime dataInicio = new DateTime(dtInicio.getYear() + 1900, dtInicio.getMonth() + 1, dtInicio.getDate(), 12, 0);
			int diasInicio = Days.daysBetween(dataInicio, dataAtual).getDays();
			precoAcerto = diasInicio * (servicoVingente.getValorMensal() / 30);
		} else {
			Contas ultimaConta = contasSessionBean.consultarUltimaContaCliente(cliente.getId());
			Date dt = ultimaConta.getDataVencimento();
			DateTime dataInicio = new DateTime(dt.getYear() + 1900, dt.getMonth() + 1, dt.getDate(), 12, 0);
			int diasUltimaC = Days.daysBetween(dataAtual, dataInicio).getDays();
			precoAcerto = diasUltimaC * (servicoVingente.getValorMensal() / 30);
		}
		Date dataA = new Date();
		dataA.setMonth(dataA.getMonth() + 1);
	
		if (precoAcerto != 0 && contasSessionBean.consultarContasAcertoClientePorServico(cliente.getId(), servicoVingente.getId()).isEmpty()) {
			Contas contaAcerto = new Contas();
			contaAcerto.setDataVencimento(dataA);
			contaAcerto.setValor(precoAcerto);
			contaAcerto.setStatusPagamento(Constantes.STATUS_ACERTO);
			contaAcerto.setServico(servicoVingente);
			contasSessionBean.registrarConta(contaAcerto);
		} else {
			Contas contaAcerto = contasSessionBean.consultarContasAcertoClientePorServico(cliente.getId(), servicoVingente.getId()).get(0);
			contaAcerto.setDataVencimento(dataA);
			contaAcerto.setValor(precoAcerto);
			contaAcerto.setStatusPagamento(Constantes.STATUS_ACERTO);
			contaAcerto.setServico(servicoVingente);
			contasSessionBean.registrarConta(contaAcerto);
		}

		Date dataAux = proxConta.getDataVencimento();
		DateTime dataProx = new DateTime(dataAux.getYear() + 1900, dataAux.getMonth() + 1, dataAux.getDate(), 12, 0);
		int dias = Days.daysBetween(dataAtual, dataProx).getDays();

		double precoProxConta = (dias * (valorAtualizado / 30));
		proxConta.setValor(precoProxConta);
		contasSessionBean.atualizarContas(proxConta);

		for (int i = 1; i < contasPendentes.size(); i++) {
			contasPendentes.get(i).setValor(valorAtualizado);
			contasSessionBean.atualizarContas(contasPendentes.get(i));
		}

	}

	public void populaServicoCategoria(List<Categoria> categorias) {
		List<ServicoCategoria> servicoCategoriasVingente = new ArrayList<ServicoCategoria>();
		for (Categoria categoria : categorias) {
			categoria = categoriaSessionBean.consultarPorCategoria(categoria.getCategoria());
			ServicoCategoria servicoCategoria = new ServicoCategoria();
			servicoCategoria.setPk(new ServicoCategoriaPK());
			servicoCategoria.getPk().setIdCategoria(categoria.getId());
			servicoCategoria.getPk().setIdServico(servicoVingente.getId());
			servicoCategoria.setCategoria(categoria);
			servicoCategoria.setServico(servicoVingente);
			servicoCategoriasVingente.add(servicoCategoria);
			servicoVingente.setServicoCategoria(servicoCategoriasVingente);
		}
	}

	public void populaServicoCategoriaRemove(List<Categoria> categoriasRemover) {
		List<ServicoCategoria> scRemover = new ArrayList<ServicoCategoria>();
		for (Categoria categoria : categoriasRemover) {
			categoria = categoriaSessionBean.consultarPorCategoria(categoria.getCategoria());
			ServicoCategoria servicoCategoria = new ServicoCategoria();
			servicoCategoria.setPk(new ServicoCategoriaPK());
			servicoCategoria.getPk().setIdCategoria(categoria.getId());
			servicoCategoria.getPk().setIdServico(servicoVingente.getId());
			servicoCategoria.setCategoria(categoria);
			servicoCategoria.setServico(servicoVingente);
			scRemover.add(servicoCategoria);
		}
		servicoVingente.setServicoCategoria(scRemover);
	}

	public void atualizarValores() {
		List<Categoria> listaAux = new ArrayList<Categoria>(categoriasCliente);
		List<Categoria> listaAuxEx = new ArrayList<Categoria>();
		valorAtualizado = 0;
		switch (tipoOp) {
		case 1:
			categoriasCliente.addAll(categoriasAdicionarCliente);
			for (Categoria categoria : categoriasCliente) {
				if (categoria.getPreco() == 0) {
					categoria = categoriaSessionBean.consultarPorCategoria(categoria.getCategoria());
				}
				valorAtualizado += categoria.getPreco();
			}
			categoriasCliente = new ArrayList<Categoria>(listaAux);
			break;

		case 2:
			for (Categoria categoria2 : categoriasRemoverCliente) {
				if (categoria2.getPreco() == 0) {
					categoria2 = categoriaSessionBean.consultarPorCategoria(categoria2.getCategoria());
					listaAuxEx.add(categoria2);
				}
			}
			categoriasCliente.removeAll(listaAuxEx);
			for (Categoria categoria : categoriasCliente) {
				if (categoria.getPreco() == 0) {
					categoria = categoriaSessionBean.consultarPorCategoria(categoria.getCategoria());
				}
				valorAtualizado += categoria.getPreco();
			}
			categoriasCliente = new ArrayList<Categoria>(listaAux);
			break;

		default:
			break;
		}

	}

	public void limparDados() {
		valorAtualizado = 0;
		categoriasAdicionarCliente.clear();
		categoriasRemoverCliente.clear();
	}

	public Servico getServicoVingente() {
		servicoVingente = servicoSessionBean.consultarServicoVingente(ClienteSessaoManagedBean.getInstance().getClienteSessao().getId());
		return servicoVingente;
	}

	public void setServicoVingente(Servico servicoVingente) {
		this.servicoVingente = servicoVingente;
	}

	public List<Categoria> getCategoriasCliente() {
		return categoriasCliente;
	}

	public void setCategoriasCliente(List<Categoria> categoriasCliente) {
		this.categoriasCliente = categoriasCliente;
	}

	public List<Categoria> getCategoriasAdicionar() {
		categoriasAdicionar = categoriaSessionBean.consultarTodasCategorias();
		if (tipoOp == 1) {
			categoriasAdicionar.removeAll(categoriasCliente);
		}
		return categoriasAdicionar;
	}

	public void setCategoriasAdicionar(List<Categoria> categoriasAdicionar) {
		this.categoriasAdicionar = categoriasAdicionar;
	}

	public double getValorAtualizado() {
		return valorAtualizado;
	}

	public void setValorAtualizado(double valorAtualizado) {
		this.valorAtualizado = valorAtualizado;
	}

	public int getTipoOp() {
		return tipoOp;
	}

	public void setTipoOp(int tipoOp) {
		this.tipoOp = tipoOp;
	}

	public List<Categoria> getCategoriasRemover() {
		categoriasRemover = new ArrayList<Categoria>(categoriasCliente);
		return categoriasRemover;
	}

	public void setCategoriasRemover(List<Categoria> categoriasRemover) {
		this.categoriasRemover = categoriasRemover;
	}

	public List<Categoria> getCategoriasAdicionarCliente() {
		return categoriasAdicionarCliente;
	}

	public void setCategoriasAdicionarCliente(List<Categoria> categoriasAdicionarCliente) {
		this.categoriasAdicionarCliente = categoriasAdicionarCliente;
	}

	public List<Categoria> getCategoriasRemoverCliente() {
		return categoriasRemoverCliente;
	}

	public void setCategoriasRemoverCliente(List<Categoria> categoriasRemoverCliente) {
		this.categoriasRemoverCliente = categoriasRemoverCliente;
	}

}
